
package com.hex.ds.code.detection.pack.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hex.ds.code.detection.common.entity.ScriptPackScanResultEntity;
import com.hex.ds.code.detection.pack.dao.ScriptPackScanListMapper;
import com.hex.ds.code.detection.pack.entity.ScriptPackEntity;
import com.hex.ds.code.detection.pack.entity.ScriptPackScanListEntity;
import com.hex.ds.code.detection.pack.service.IScriptPackScanListService;
import com.hex.ds.code.detection.pack.service.IScriptPackScanResultService;
import com.hex.ds.code.detection.common.base.PageResult;
import com.hex.ds.code.detection.common.constants.CommonConstants;
import liquibase.pro.packaged.L;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 脚本打包扫描清单
 *
 * @author Wang zhihao
 * @date 2023-09-13 18:05:43
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy, @Autowired})
public class ScriptPackScanListServiceImpl extends ServiceImpl<ScriptPackScanListMapper, ScriptPackScanListEntity> implements
    IScriptPackScanListService {

    private final ScriptPackScanListMapper scriptPackScanListMapper;

    private final IScriptPackScanResultService scriptPackScanResultService;

    /**
     * @Method queryList
     * @Param
     * @param page
     * @param scriptPackScanList
     * @Return com.hex.ds.code.detection.common.base.PageResult
     * @Description 分页查询并返回PageResult类型的对象
     * @Author Wang zhihao
     * @Date 2023/9/14 16:41
     * @Version V1.0
     */
    @Override
    public PageResult queryList(Page page, ScriptPackScanListEntity scriptPackScanList) {
        LambdaQueryWrapper<ScriptPackScanListEntity> wrapper = beforeQuery(scriptPackScanList);
        Page returnPage = this.baseMapper.selectPage(page, wrapper);
        List<ScriptPackScanListEntity> records = page.getRecords();
        List<ScriptPackEntity> scriptPackEntityList = new ArrayList<>();
        for (ScriptPackScanListEntity record : records) {
            ScriptPackEntity newScriptPackScanListEntity = getNewScriptPackScanListEntity(record);
            scriptPackEntityList.add(newScriptPackScanListEntity);
        }
        Page newPage = new Page<>();
        newPage.setTotal(returnPage.getTotal());
        newPage.setRecords(scriptPackEntityList);
        return new PageResult(newPage.getRecords(), newPage.getTotal());
    }

    @Override
    public List<ScriptPackScanListEntity> queryListNoPage(ScriptPackScanListEntity scriptPackScanList) {
        LambdaQueryWrapper<ScriptPackScanListEntity> wrapper = beforeQuery(scriptPackScanList);
        wrapper.eq(StrUtil.isNotBlank(scriptPackScanList.getScriptPackTaskId()), ScriptPackScanListEntity::getScriptPackTaskId, scriptPackScanList.getScriptPackTaskId());
        return this.baseMapper.selectList(wrapper);
    }

    @Override
    public List<ScriptPackScanListEntity> getListByTaskId(String taskId) {
        return queryListNoPage(new ScriptPackScanListEntity().setScriptPackTaskId(taskId));
    }

    /**
     * @Method getFailResultByTaskId
     * @Param
     * @param taskId
     * @Return java.util.List<java.lang.String>
     * @Description 根据任务Id获取失败的文件
     * @Author Wang zhihao
     * @Date 2023/12/25 20:30
     * @Version V1.0
     */
    @Override
    public List<String> getFailFileByTaskId(String taskId) {
        List<ScriptPackScanListEntity> scriptPackScanListEntities = queryListNoPage(new ScriptPackScanListEntity().setScriptPackTaskId(taskId));
        return scriptPackScanListEntities.stream()
                .filter(s -> StrUtil.equalsAnyIgnoreCase(s.getScanState(), "FAIL", "WARNING", "UNSCAN"))
                .map(ScriptPackScanListEntity::getScanFileName)
                .collect(Collectors.toList());
    }

    /**
     * @Method beforeQuery
     * @Param
     * @param scriptPackScanList
     * @Return com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.hex.ds.code.detection.script.pack.entity.ScriptPackScanListEntity>
     * @Description 查询前置操作
     * @Author Wang zhihao
     * @Date 2023/10/17 16:55
     * @Version V1.0
     */
    private LambdaQueryWrapper<ScriptPackScanListEntity> beforeQuery(ScriptPackScanListEntity scriptPackScanList) {
        LambdaQueryWrapper<ScriptPackScanListEntity> wrapper = Wrappers.lambdaQuery();
        if (StrUtil.isNotBlank(scriptPackScanList.getScriptPackTaskId())) {
            wrapper.eq(ScriptPackScanListEntity::getScriptPackTaskId, scriptPackScanList.getScriptPackTaskId());
        }
        if (StrUtil.isNotBlank(scriptPackScanList.getFileAffiliation())) {
            wrapper.eq(ScriptPackScanListEntity::getFileAffiliation, scriptPackScanList.getFileAffiliation());
        }
        if (StrUtil.isNotBlank(scriptPackScanList.getScanFileName())) {
            wrapper.like(ScriptPackScanListEntity::getScanFileName, scriptPackScanList.getScanFileName());
        }
        return wrapper;
    }

    /**
     * @Method updateStatus
     * @Param
     * @param id
     * @param status
     * @Return void
     * @Description 根据Id修改状态
     * @Author Wang zhihao
     * @Date 2023/9/15 18:27
     * @Version V1.0
     */
    @Override
    public void updateStatus(String id, String status) {
        ScriptPackScanListEntity scriptPackScanList = new ScriptPackScanListEntity().setId(id).setScanState(status);
        scriptPackScanListMapper.updateById(scriptPackScanList);
    }

    /**
     * @Method refreshStateById
     * @Param
     * @param id
     * @Return void
     * @Description 根据ID刷新状态
     * @Author Wang zhihao
     * @Date 2023/12/19 18:05
     * @Version V1.0
     */
    @Override
    public void refreshStateById(String id) {
        ScriptPackScanListEntity scriptPackScanList = new ScriptPackScanListEntity().setId(id);
        List<ScriptPackScanResultEntity> scriptPackScanResultEntities = scriptPackScanResultService.queryListNoPage(new ScriptPackScanResultEntity().setScanListId(id));
        if (scriptPackScanResultEntities.stream().allMatch(s -> s.getScanState().equals("success") || s.getScanState().equals("default"))) {
            scriptPackScanList.setScanState("SUCCESS");
            updateById(scriptPackScanList);
        }
        if (scriptPackScanResultEntities.stream().allMatch(s -> s.getScanState().equals("success") || s.getScanState().equals("default") || s.getScanState().equals("ignore"))) {
            scriptPackScanList.setScanState("IGNORE");
            updateById(scriptPackScanList);
        }
    }

    @Override
    public void removeByTaskId(String taskId) {
        List<ScriptPackScanListEntity> scriptPackScanListEntities = queryListNoPage(new ScriptPackScanListEntity().setScriptPackTaskId(taskId));
        List<String> listIds = scriptPackScanListEntities.stream().map(ScriptPackScanListEntity::getId).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(listIds)) {
            removeByIds(listIds);
        }
    }

    public void removeByIds(List<String> listIds) {
        for (String listId : listIds) {
            scriptPackScanResultService.removeByListId(listId);
            updateById(new ScriptPackScanListEntity().setId(listId).setDel(CommonConstants.STATUS_DEL));
        }
    }

    /**
     * @Method batchIgnoreById
     * @Param
     * @param id
     * @Return void
     * @Description 根据ID批量忽略
     * @Author Wang zhihao
     * @Date 2023/12/19 18:05
     * @Version V1.0
     */
    @Override
    public void batchIgnoreById(String id) {
        List<ScriptPackScanResultEntity> scriptPackScanResultEntities = scriptPackScanResultService.queryListNoPage(new ScriptPackScanResultEntity().setScanListId(id));
        scriptPackScanResultEntities = scriptPackScanResultEntities.stream().filter(s -> s.getScanState().equals("warning")).collect(Collectors.toList());
        for (ScriptPackScanResultEntity scriptPackScanResult : scriptPackScanResultEntities) {
            scriptPackScanResultService.ignoreById(scriptPackScanResult);
        }
        refreshStateById(id);
    }

    /**
     * @Method getNewScriptPackScanListEntity <br>
     * @Param scriptPackScanList <br>
     * @Return com.hex.ds.code.detection.pack.entity.ScriptPackScanListEntity <br>
     * @Description <br>
     * @Author ky.zhang<br>
     * @Date 2024/9/14 15:04 <br>
     * @Version V1.0<br>
     */
    @Override
    public ScriptPackEntity getNewScriptPackScanListEntity(ScriptPackScanListEntity scriptPackScanList) {
        ScriptPackEntity scriptPackEntity = new ScriptPackEntity();
        BeanUtil.copyProperties(scriptPackScanList,scriptPackEntity);
        String scanFilePath = scriptPackEntity.getScanFilePath();
        Path path = Paths.get(scanFilePath);
        String packName = path.getParent().getFileName().toString();
        scriptPackEntity.setScanPackName(packName);
        return scriptPackEntity;
    }
}
